package com.zjj.learn.algorithmPlus.segment1.array;

import com.zjj.learn.algorithmPlus.util.Util;

/**
 * @author zjj_admin
 */
public class Array1 {

    public static void main(String[] args) {
        int row = 1000000;
        int col = 14;
        int[][] nums = new int[row][col];
        //获取执行 ij 方法的时间，先遍历行再遍历列
        long timeIJ = Util.runningTime(() -> ij(nums, row, col));
        //获取执行 ji 方法的时间，先遍历列再遍历行
        long timeJI = Util.runningTime(() -> ji(nums, row, col));

        System.out.println("timeIJ = " + timeIJ);
        System.out.println("timeJI = " + timeJI);

    }


    /**
     * 遍历，先遍历行，再遍历列
     *
     * @param nums
     * @param row
     * @param col
     */
    public static long ij(int[][] nums, int row, int col) {
        long num = 0L;
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                num += nums[i][j];
            }
        }
        return num;
    }

    /**
     * 遍历，先遍历列，再遍历行
     *
     * @param nums
     * @param row
     * @param col
     */
    public static long ji(int[][] nums, int row, int col) {
        long num = 0L;
        for (int j = 0; j < col; j++) {
            for (int i = 0; i < row; i++) {
                num += nums[i][j];
            }
        }
        return num;
    }


    /**
     * 一维数组
     *
     * 1、在数组中所有的数据在内存中的地址是连续的。
     * 例如：int[] a = new int[]{1,2,3,4}，若 数据 1 的内存地址为 ADDRESS，则数据 3 的内存地址为 ADDRESS + 4 * 2。
     *
     * 指导了某一个数组的起始地址为 baseAddress，那么索引为 index 的地址为 baseAddress + index * size，size 表示每一个数据的大小。
     *
     * 2、数组的空间占用
     *    a：8 个字节的 markword；
     *    b：4 个字节的 class 指针（压缩 class 的情况）
     *    c：4 个字节存储数组的大小（决定了数组的最大存储元素 2^32 个）
     *    d：数组元素 + 对齐字节（在 Java 中所有的对象数据占用内存都是 8 的整数倍个字节，若不是就会补 0，直到是 8 的整数倍）
     *
     *    随机访问，知道索引就和数组的规模没有关系。O(1)，只要知道了索引就可以马上计算出数据的内存地址。
     *
     *
     * 3、动态数组【Java 实现的动态数字：ArrayList】
     *    实现随着数据的添加个删除逐步修改数据的大小。
     *    a：添加数据
     *    b：根据索引获取数据
     *    c：遍历数据，自定义 for 循环
     *    d：实现数字的迭代器功能，实现增强 for 功能，for(Integer item : array){} 的格式
     *    e：实现数组的删除功能。
     *    f：实现数据的动态扩容
     *
     *    插入或者删除的性能。时间复杂度
     *      插入【删除】头部：O(n)
     *      插入【删除】中间：O(n)
     *      插入【删除】尾部：O(1) 不需要考虑扩容
     *
     *
     * 二维数组：
     *
     * 1、
     *    二维数组的内存分布，二维数组如何定位数据。
     *    二位数组遍历时，先遍历行和先遍历列的执行效率有区别吗？有区别，这个和缓存相关了。
     *
     */
}
